
#include "TFGame.h"
#include "TFMenu.h"

TFMenu::TFMenu(){
	xCenter = 265/2 - 64/2;				//Center of screen.
	yCurrent = 50;						//Y position to place first menu item.
	itemCount = 0;						//# of items (starts at 1, 0 reserved for selection).
	paletteCount = 0;					//# of palettes (starts at 0).
	currentPalette = 0;					//Active palette.
	memset(palettes, 0 , 10);			
	selectedCurrent = 0;
	selectorSpriteIndex = 0;			//Selector sprite always at index 0;
	_menuMode = MAIN_MENU;

										//Initialize zoom/rotsets
	u16 zoomNormal = 230;				//256: no zoom
	u16 zoomSmaller = 300;
	PA_SetRotsetNoAngle(0,1, zoomSmaller, zoomSmaller); 
	PA_SetRotsetNoAngle(0,0, zoomNormal, zoomNormal); 
}

TFMenu::~TFMenu(){
    DestroyMenu();
}

TF_MENU_MODE TFMenu::GetMenuMode()
{
	return _menuMode;
}

void TFMenu::SetMenuMode(TF_MENU_MODE menuMode)
{
	_menuMode = menuMode;
}

void TFMenu::DestroyMenu()
{
    for (int i=1; i <= itemCount; i++)
    {
        PA_DeleteSprite(0,i);
    }
    PA_DeleteSprite(0, selectorSpriteIndex);
}

/* Adds a sprite item to the menu list */
int TFMenu::AddMenuItem(void* sprite, unsigned short* palette)
{
	itemCount++;
	SetPalette(palette);

	PA_LoadSpritePal(0,			// Screen
			currentPalette,		// Palette number
			(void*)palette);	// Palette name
					
	PA_CreateSprite(0,			// Screen
			itemCount,			// Sprite number
			(void*)sprite,		// Sprite name
			OBJ_SIZE_64X32,		// Sprite size
			1,					// 256 color mode
			currentPalette,		// Sprite palette number
			xCenter, yCurrent); // X and Y position on the screen

	yCurrent = yCurrent + 25;
	UpdateScale();
	return itemCount;
}

/*Adds the sprite that acts as the menu selection feedback, currently
 *a dotted yellow line, but we could use a faded sprite or an animation 
 *or anything... */
void TFMenu::AddMenuSelect(void* sprite,unsigned short* palette, int index){
	selectedCurrent = index;
	UpdateScale();

	SetPalette(palette);
	
	PA_LoadSpritePal(0,			// Screen
			currentPalette,		// Palette number
			(void*)palette);	// Palette name
					
	PA_CreateSprite(0,			// Screen
			selectorSpriteIndex,// Sprite number
			(void*)sprite,		// Sprite name
			OBJ_SIZE_64X32,		// Sprite size
			1,					// 256 color mode
			currentPalette,		// Sprite palette number
			xCenter,PA_GetSpriteY(0,index)); // X and Y position on the screen

}

void TFMenu::ChangeSprite(void* sprite,unsigned short* palette, int index){
	SetPalette(palette);

	PA_LoadSpritePal(0,			// Screen
			currentPalette,		// Palette number
			(void*)palette);	// Palette name
					
	PA_CreateSprite(0,			// Screen
			index,				// Sprite number
			(void*)sprite,		// Sprite name
			OBJ_SIZE_64X32,		// Sprite size
			1,					// 256 color mode
			currentPalette,		// Sprite palette number
			PA_GetSpriteX(0,index), PA_GetSpriteY(0,index)); // X and Y position on the screen

	yCurrent = yCurrent + 25;
	UpdateScale();
}

/* Syncs the display */
void TFMenu::Display(){
	PA_WaitForVBL();
}

/* Sets the palette to load the current menu item on. */
void  TFMenu::SetPalette(unsigned short* pal){
	for(int i=0;i<10;i++){
		if(palettes[i] != 0){
			if(palettes[i] == (unsigned short*)pal){
				currentPalette = i;
				return;
			}
		}else{
			palettes[i] = (unsigned short*)pal;
			currentPalette = i;
			return;
		}
	}
}

/* Moves the selector sprite, loops around. */
void TFMenu::ChangeSelected(int direction){
	//direction: 0=up,  1=down;

	if(direction == MENU_DOWN){
		if(selectedCurrent == itemCount){
			PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0,1));
			selectedCurrent = 1;
		}else{
			PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0, selectedCurrent + 1));
			selectedCurrent++;
		}
	}else if(direction == MENU_UP){
		if(selectedCurrent == 1){
			PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0,itemCount));
			selectedCurrent = itemCount;
		}else{
			PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0, selectedCurrent - 1));
			selectedCurrent--;
		}
	}

	UpdateScale();
	PA_WaitForVBL();
}

void TFMenu::SetSelectedElement(int element)
{
	if (element > 0 && element <= itemCount)
	{
		selectedCurrent = element;
		PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0, selectedCurrent));
		UpdateScale();
		PA_WaitForVBL();
	}
}

/* Returns current selected item, used to determine next menu to display by main loop. */
int TFMenu::GetSelected(){
	return selectedCurrent;
}

TF_MENU_OPTION TFMenu::GetSelectedOption()
{
	return ONE_PLAYER;
}

/* Takes x,y stylus position and moves the selector and returns the menu item index. */
int TFMenu::StylusSelect(int x, int y){
	int yValue = 50;							//Where we start menu at.
	if(x > xCenter && x < xCenter+64){
		for(int i=1;i<=itemCount;i++){
			if(y > yValue && y < yValue + 25){
				selectedCurrent = i;
				PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0, i));
				UpdateScale();
				PA_WaitForVBL();
				return i;
			}

			yValue = yValue + 25;
		}
	}
	return 0;
}

void TFMenu::ShowMenu()
{
	int yVal=50;

	for(int i=1;i<=itemCount;i++)
	{
		PA_SetSpriteXY(0, i, xCenter, yVal);
		yVal+=25;
	}
	PA_SetSpriteXY(0, selectorSpriteIndex, xCenter, PA_GetSpriteY(0, selectedCurrent));
}

void TFMenu::HideMenu()
{
	for(int i=1;i<=itemCount;i++)
	{
		PA_SetSpriteXY(0, i, 300,300);
	}
	PA_SetSpriteXY(0,0,300,300);
}

/* Possible good effect, doesn't seem to work in my emulator though. */
void TFMenu::FadeOut(){
	s16 alpha = 7; // Transparency level

	for(int i=1;i<=itemCount;i++){
		PA_SetSpriteMode(0, // Screen
 				 i, // Sprite
				 1); // Alphablending

	} 

	// Enable the alpha-blending
	PA_EnableSpecialFx(0, // Screen
				   SFX_ALPHA, // Alpha blending mode
				   0, // Nothing
			   SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD); // Everything normal

	PA_SetSFXAlpha(0, // Screen
			alpha, // Alpha level, 0-15
			15); // Leave this to 15
 
	PA_WaitForVBL();
}

void TFMenu::FadeIn()
{
    s16 alpha = 15;
    PA_SetSFXAlpha(0, alpha, 15);
    PA_WaitForVBL();
}

/* This makes the selected sprite larger then the unselected ones. */
void TFMenu::UpdateScale(){
	for(int i=1;i<=itemCount;i++){
		if(i != selectedCurrent){		//scale down
			PA_SetSpriteRotEnable(0,i,1);
		}
		else{							//scale normal
			PA_SetSpriteRotEnable(0,i,0);
		}
	}        
}
